/**
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.
*/

package org.elephantt.webby;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import java.io.IOException;

/**
 * A response served by a JSP template and an optional model.
 * The default status code is 200, but this can be overridden. However, status codes must be in the
 * Successful/2xx series or Redirection/3xx series. 4xx and 5xx responses should use the ErrorResponse
 * instead.
 */
public class JspViewResponder implements Responder {
  private final String resourcePath;
  private final String suffix;

  public JspViewResponder(String resourcePath, boolean usingJspx) {
    this.resourcePath = resourcePath;
    suffix = usingJspx ? ".jspx" : ".jsp";
  }

  public JspViewResponder(String resourcePath) {
    this(resourcePath, false);
  }

  public JspViewResponder() {
    this("");
  }

  public void respond(HttpServletRequest request, HttpServletResponse response, Object controllerReturnValue) throws IOException {
    JspView jspView;

    if (controllerReturnValue instanceof JspView) {
      jspView = (JspView) controllerReturnValue;
    } else {
      RequestMapping mapping = (RequestMapping) request.getAttribute(ServletRequestAttributes.REQUEST_MAPPING);
      assert mapping != null : "request missing required attribute " + ServletRequestAttributes.REQUEST_MAPPING;
      jspView = new JspView(mapping.getViewNamePrefix() + suffix, controllerReturnValue);
    }

    RequestUtil.markRequestInternal(request);
    RequestUtil.copyModelToRequestAttributes(jspView.getModel(), request);

    RequestDispatcher jspDispatcher = request.getRequestDispatcher(resourcePath + jspView.getFilename());
    if (jspDispatcher != null) {
      try {
        jspDispatcher.forward(request, response);
      } catch (ServletException e) {
        throw new WebbyException("error dispatching to JSP dispatcher", e);
      }
    } else {
      throw new RuntimeException("no JSP dispatcher for path " + jspDispatcher + " -- check your web.xml");
    }
  }
}